//
// Created on 2025/7/26.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".

#ifndef OPENGL_IMAGE_RENDER_SHADERS_H
#define OPENGL_IMAGE_RENDER_SHADERS_H
namespace HarmonyVideoEditorRender {
namespace Detail {
// 顶点着色器（GLSL ES 300）
const char *imageVertexShader = R"delimiter(#version 300 es
layout (location = 0) in vec3 position;  // 使用location指定属性位置，替代attribute
layout (location = 1) in vec2 texCoord;

out vec2 vTexCoord;  // 300 es中使用out替代varying

uniform mat4 matTransform;
uniform mat4 orthoMatrix;  // 正交矩阵，通过参数传入

void main()
{
    // 应用正交矩阵和变换矩阵
    gl_Position =  orthoMatrix * matTransform * vec4(position, 1.0);
    vTexCoord = texCoord;  // 传递纹理坐标到片段着色器
}
)delimiter";

// 片段着色器（GLSL ES 300）
const char *imageFragmentShader = R"delimiter(#version 300 es
precision mediump float;
precision mediump sampler2DArray;
in vec2 vTexCoord;
out vec4 FragColor;

// 输入参数：控制转换逻辑（新增纹理数组和帧索引）
uniform sampler2DArray texArray;       // 纹理数组采样器（替代原sampler2D）
uniform int uFrameIndex;               // 帧索引（新增）
uniform bool isInputP3;                // 输入是否为 P3 色域（false 为 sRGB）
uniform bool isInputFullRange;         // 输入是否为全范围（0-255）
uniform bool needGammaToLinear;        // 是否需要手动gamma转线性空间


vec3 limitedToFull(vec3 color) {
    return (color - 0.062745098) / 0.8784313725;
}

// -------------------------- Gamma 转换 --------------------------
vec3 gammaToLinear(vec3 color) {
    return mix(
        color / 12.92,
        pow((color + 0.055) / 1.055, vec3(2.4)),
        step(0.04045, color)
    );
}

vec3 linearToBt709Gamma(vec3 linearColor) {
    return mix(
        linearColor * 12.92,
        1.055 * pow(linearColor, vec3(1.0 / 2.4)) - 0.055,
        step(0.0031308, linearColor)
    );
}

// -------------------------- 色域转换矩阵（线性空间） --------------------------
const mat3 P3_TO_BT709 = mat3(
    0.8224614861,  0.1775385139,  0.0,
    0.0497641251,  0.9502358749,  0.0,
    0.0000000000,  0.0201854428,  0.9798145572
);

const mat3 SRGB_TO_BT709 = mat3(
    1.006566755,  -0.006575569,  0.0,
    -0.001881182,  1.001888774,  0.0,
    0.000021855,  -0.000456455,  1.0004346
);

void main() {
    // 1. 采样输入颜色（使用纹理数组和帧索引）
    vec3 inputColor = texture(texArray, vec3(vTexCoord, float(uFrameIndex))).rgb;

    // 2. 范围统一（转为全范围，方便后续处理）
    vec3 color = inputColor;
    if (!isInputFullRange) {
        color = limitedToFull(color);
    }

    // 3. 伽马转换（根据参数决定是否手动转为线性空间）
    vec3 linearColor = needGammaToLinear ? gammaToLinear(color) : color;

    // 4. 线性空间下进行色域转换
    if (isInputP3) {
        linearColor = P3_TO_BT709 * linearColor;
    } else {
        linearColor = SRGB_TO_BT709 * linearColor;
    }

    // 5. 输出线性空间值（范围[0,1]）
    FragColor = vec4(clamp(linearColor, 0.0, 1.0), 1.0);
}
)delimiter";

const char *videoVertexShader = R"delimiter(#version 300 es

layout(location = 0) in vec3 position;  // 替换 attribute 为 in，并添加 layout 位置
layout(location = 1) in vec2 texCoord;   // 替换 attribute 为 in，并添加 layout 位置

out vec2 vTexCoord;                     // 替换 varying 为 out

uniform mat4 matTransform;

void main()
{
    gl_Position = matTransform * vec4(position, 1.0);
    vTexCoord = texCoord;
}
)delimiter";

const char *videoFragmentShader = R"delimiter(#version 300 es
#extension GL_EXT_YUV_target : require
#extension GL_OES_EGL_image_external_essl3 : require
precision highp float;

in vec2 vTexCoord;
uniform highp __samplerExternal2DY2YEXT sTexture;

uniform bool isInputBt601;       // 输入是否为BT.601色彩空间
uniform bool isInputFullRange;  // 输入是否为Full Range

out vec3 FragColor;

// BT.601到BT.709的YUV转换矩阵
const mat3 BT601_TO_BT709_YUV = mat3(
    1.0,  0.0,  0.0,
    0.0,  0.989,  0.011,
    0.0,  0.011,  0.989
);

void main() {
    // 1. 采样YUV数据
    vec3 yuv = texture(sTexture, vTexCoord).rgb;
    
    // 2. 在YUV空间处理range转换
    if (!isInputFullRange) {
        // Limited Range YUV → Full Range YUV
        yuv.x = (yuv.x - 0.062745098) / 0.8588;  // Y分量: (Y-16)/219
        yuv.y = (yuv.y - 0.5) / 0.8784 + 0.5;    // U分量: (U-128)/224 + 0.5
        yuv.z = (yuv.z - 0.5) / 0.8784 + 0.5;    // V分量: (V-128)/224 + 0.5
    }
    
    // 3. 色域转换（如果需要从BT.601转换到BT.709）
    if (isInputBt601) {
        // 在YUV空间进行BT.601到BT.709转换
        yuv = BT601_TO_BT709_YUV * yuv;
    }

    // 6. YUV→RGB转换
    vec3 rgb;
    if (isInputBt601) {
        rgb.r = yuv.x + 1.402 * (yuv.z - 0.5);
        rgb.g = yuv.x - 0.344 * (yuv.y - 0.5) - 0.714 * (yuv.z - 0.5);
        rgb.b = yuv.x + 1.772 * (yuv.y - 0.5);
    }else{
        rgb.r = yuv.x + 1.5748 * (yuv.z - 0.5);
        rgb.g = yuv.x - 0.1873 * (yuv.y - 0.5) - 0.4681 * (yuv.z - 0.5);
        rgb.b = yuv.x + 1.8556 * (yuv.y - 0.5);
    }
    // 7. 最终限制RGB范围并输出
    rgb = clamp(rgb, 0.0, 1.0);
    FragColor = rgb;
}
)delimiter";
} // namespace Detail
} // namespace HarmonyVideoEditorRender
#endif // OPENGL_IMAGE_RENDER_SHADERS_H
